package com.ys.service.bi.impl;

import com.alibaba.fastjson.JSONObject;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.ys.entity.bi.BiFlowAnalysis;
import com.ys.entity.finance.TcwFinancialTransactionType;
import com.ys.enume.bi.BiFlowAnalysisEnum;
import com.ys.mapper.bi.BiFlowAnalysisMapper;
import com.ys.mapper.bi.BiMapper;
import com.ys.service.bi.BiFlowAnalysisService;
import com.ys.util.DateUtil;
import com.ys.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 流水分析统计汇总表
 */
@Service("biFlowAnalysisService")
public class BiFlowAnalysisServiceImpl implements BiFlowAnalysisService {
	private static final Logger logger = LoggerFactory.getLogger(BiFlowAnalysisServiceImpl.class);

	@Autowired
	private BiMapper biMapper;

	@Autowired
	private BiFlowAnalysisMapper biFlowAnalysisMapper;


	//每天定时更新
	@Override
	@Transactional
	public R doCountByDaily()throws Exception {
		//刷取日数据
		updateByDay();

		Date today = new Date();
		String monthStr =  DateUtil.getMM(today);
		String dayStr = DateUtil.getDD(today);

		//刷取月数据
		String yesterdayMonth =  DateUtil.getYYYY_MM(DateUtil.addDays(today, -1));//昨日月份
		updateByMonth(yesterdayMonth);
		if(dayStr.equals("01")) {//如果是月份第一天，刷取当月数据
			String thisMonth =  DateUtil.getYYYY_MM(today);
			updateByMonth(thisMonth);
		}

		//刷取年数据
		String yesterdayYear =  DateUtil.getYYYY(DateUtil.addDays(today, -1));//昨日年份
		updateByYear(yesterdayYear);
		if(monthStr.equals("01") && dayStr.equals("01")) {//新年第一天，刷取本年数据
			String thisYear =  DateUtil.getYYYY(today);
			updateByMonth(thisYear);
		}

		return R.ok();
	}

	//每天定时更新汇总表
	@Override
	public R updateByDay()throws Exception {
		Date today = new Date();
		String yesterday =  DateUtil.getYYYY_MM_DD(DateUtil.addDays(today, -1));//昨日日期
		//String beforeYesterday =  DateUtil.getYYYY_MM_DD(DateUtil.addDays(today, -2));//前日日期
		//先删除全部的汇总表信息
		biMapper.delBiFlowAnalysisByStatDate(yesterday);
		getCount(yesterday+" 00:00:00",yesterday+" 23:59:59",yesterday,0,false);
		//getCount(beforeYesterday+" 00:00:00",beforeYesterday+" 23:59:59",yesterday,0,false);
		return R.ok();
	}


	/*
	 * 根据月份刷取
	 */
	@Override
	public R updateByMonth(String month)throws Exception {
		String startTime = month+"-01 00:00:00";

		Date today = new Date();
		String thisMonth =  DateUtil.getYYYY_MM(today);
		//先删除
		biMapper.delBiFlowAnalysisByStatDate(month);
		if(month.equals(thisMonth)){//如果是当月
			String dayStr = DateUtil.getDD(today);
			if(dayStr.equals("01")){//如果是月份第一天，月度累计为0
				getCount(startTime,"",month,1,true);
			}else {//如果不是月份第一天
				//结束时间为昨日
				String yesterday =  DateUtil.getYYYY_MM_DD(DateUtil.addDays(today, -1));//昨日日期
				String endTime = yesterday +" 23:59:59";
				getCount(startTime,endTime,month,1,false);
			}
		}else {
			int lastDay = DateUtil.getMonthLastDay(month);//获取月份的最后一天
			String endTime = month+"-"+lastDay+" 23:59:59";
			getCount(startTime,endTime,month,1,false);
		}

		return R.ok();
	}

	/*
	 * 根据年份刷取
	 */
	@Override
	public R updateByYear(String year)throws Exception {
		String startTime = year+"-01-01 00:00:00";
		Date today = new Date();
		String thisMonth =  DateUtil.getMM(today);
		String dayStr = DateUtil.getDD(today);
		String thisYear =  DateUtil.getYYYY(today);

		//先删除
		biMapper.delBiFlowAnalysisByStatDate(year);
		if(year.equals(thisYear)){//如果是今年
			if(thisMonth.equals("01") && dayStr.equals("01")){//新年第一天
				getCount(startTime,"",year,2,true);
			}else {//如果不是新年第一天
				//统计的结束时间到昨日
				String yesterday =  DateUtil.getYYYY_MM_DD(DateUtil.addDays(today, -1));//昨日日期
				String endTime = yesterday +" 23:59:59";
				getCount(startTime,endTime,year,2,false);
			}
		}else {
			String endTime = year+"-12-31 23:59:59";
			getCount(startTime,endTime,year,2,false);
		}



		return R.ok();
	}

	/**
	 * 更新汇总表
	 * @param startTime 统计开始时间
	 * @param endTime 统计结束时间
	 * @param statDate 统计日期（yyyy-mm-dd、yyyy-mm）
	 * @param statDateType 统计日期类型（0按日、1按月）
	 * @param isZero 是否直接填入0
	 * @throws Exception
	 */
	public void getCount(String startTime,String endTime,String statDate,int statDateType,boolean isZero)throws Exception {
		logger.info("开始时间："+startTime+"-结束时间："+endTime);
		//获取财务交易类型
		List<TcwFinancialTransactionType> typeList = new TcwFinancialTransactionType().setStatus(1).queryList();

		//收入
		List<Map<String, Object>> countByIncome = new ArrayList<>();
		//支出
		List<Map<String, Object>> countByOutcome = new ArrayList<>();
		//利润
		List<Map<String, Object>> countByProfit = new ArrayList<>();

		if(!isZero){
			//收入
			countByIncome = biMapper.countBiFlowAnalysis(startTime, endTime, BiFlowAnalysisEnum.DataType.INCOME.value);
			//支出
			countByOutcome = biMapper.countBiFlowAnalysis(startTime, endTime, BiFlowAnalysisEnum.DataType.OUTCOME.value);
			//利润
			countByProfit = biMapper.countBiFlowAnalysis(startTime, endTime, BiFlowAnalysisEnum.DataType.PROFIT.value);
		}

		if(typeList!=null && typeList.size()>0){

			//再遍历新增
			for(TcwFinancialTransactionType typeItem:typeList){
				String bid = typeItem.getBid();


				//logger.info("获取管理类型："+bid+"-"+typeItem.getIntegrityType());
				BigDecimal incomeAmount = BigDecimal.ZERO;//收入统计金额
				BigDecimal outcomeAmount = BigDecimal.ZERO;//支出统计金额
				BigDecimal profitAmount = BigDecimal.ZERO;//利润统计金额

				if(!isZero){
					if(countByIncome!=null && countByIncome.size()>0){
						List<Map<String, Object>> countByIncomeByBid = countByIncome.stream().filter(item->item.get("bid").toString().equals(bid)).collect(Collectors.toList());
						if(countByIncomeByBid.size()>0){
							incomeAmount = new BigDecimal(countByIncomeByBid.get(0).get("amount").toString());
						}
					}
					if(countByOutcome!=null && countByOutcome.size()>0){
						List<Map<String, Object>> countByOutcomeByBid = countByOutcome.stream().filter(item->item.get("bid").toString().equals(bid)).collect(Collectors.toList());
						if(countByOutcomeByBid.size()>0){
							outcomeAmount = new BigDecimal(countByOutcomeByBid.get(0).get("amount").toString());
						}
					}
					if(countByProfit!=null && countByProfit.size()>0){
						List<Map<String, Object>> countByProfitByBid = countByProfit.stream().filter(item->item.get("bid").toString().equals(bid)).collect(Collectors.toList());
						if(countByProfitByBid.size()>0){
							profitAmount = new BigDecimal(countByProfitByBid.get(0).get("amount").toString());
						}
					}
				}


				//收入
				BiFlowAnalysis entity0 = new BiFlowAnalysis();
				entity0.setFinancialTransactionTypeBid(bid);//财务分类表bid
				entity0.setStatDate(statDate);//统计日期（yyyy-mm-dd、yyyy-mm）
				entity0.setStatDateType(statDateType);//统计日期类型（0按日、1按月）
				entity0.setStatus(1);
				entity0.setDataType(BiFlowAnalysisEnum.DataType.INCOME.value);
				entity0.setAmount(incomeAmount);
				biFlowAnalysisMapper.insert(entity0);

				//支出
				BiFlowAnalysis entity1 = new BiFlowAnalysis();
				entity1.setFinancialTransactionTypeBid(bid);//财务分类表bid
				entity1.setStatDate(statDate);//统计日期（yyyy-mm-dd、yyyy-mm）
				entity1.setStatDateType(statDateType);//统计日期类型（0按日、1按月）
				entity1.setStatus(1);
				entity1.setDataType(BiFlowAnalysisEnum.DataType.OUTCOME.value);
				entity1.setAmount(outcomeAmount.abs());//存绝对值
				biFlowAnalysisMapper.insert(entity1);

				//利润
				BiFlowAnalysis entity2 = new BiFlowAnalysis();
				entity2.setFinancialTransactionTypeBid(bid);//财务分类表bid
				entity2.setStatDate(statDate);//统计日期（yyyy-mm-dd、yyyy-mm）
				entity2.setStatDateType(statDateType);//统计日期类型（0按日、1按月）
				entity2.setStatus(1);
				entity2.setDataType(BiFlowAnalysisEnum.DataType.PROFIT.value);
				entity2.setAmount(profitAmount);
				biFlowAnalysisMapper.insert(entity2);

			}

		}
	}


	//bi页面获取数据，根据日期类型
	//dateType 0昨日、1本月、2本年
	@Override
	public JSONObject getInfoByDateType(int dateType)throws Exception {
		JSONObject res = new JSONObject();

		//******获取头部数据******

		Date today = new Date();
		String todayStr = DateUtil.getYYYY_MM_DD(today);
		String yesterday = DateUtil.getYYYY_MM_DD(DateUtil.addDays(today, -1));//昨日日期
		String thisMonth =  DateUtil.getYYYY_MM(today);//当月
		String beforeMonth =  DateUtil.getYYYY_MM(DateUtil.addMonth(today, -1));//上个月
		String lastYearMonth =  DateUtil.getYYYY_MM(DateUtil.addMonth(today, -12));//去年的当月
		String thisYear =  DateUtil.getYYYY(today);//今年
		String beforeYear = lastYearMonth.substring(0, 4);//去年

		//BiFlowAnalysis lastInfo = new BiFlowAnalysis().setOrderby("A.Id DESC").queryFirst();
		//String lastTime = DateUtil.getYYYY_MM_DD_HH_mm_ss(lastInfo.getCreateTime());
		res.put("lastTime",todayStr+" 00:00:01");//最新刷新时间

		BigDecimal totalIncome = BigDecimal.ZERO;//总收入
		BigDecimal totalOutcome = BigDecimal.ZERO;//总支出
		BigDecimal totalProfit = BigDecimal.ZERO;//总利润

		BigDecimal relativeIncome = BigDecimal.ZERO;//收入环比
		BigDecimal relativeOutcome = BigDecimal.ZERO;//支出环比
		BigDecimal relativeProfit = BigDecimal.ZERO;//利润环比

		BigDecimal sameRatioIncome = BigDecimal.ZERO;//收入同比
		BigDecimal sameRatioOutcome = BigDecimal.ZERO;//支出同比
		BigDecimal sameRatioProfit = BigDecimal.ZERO;//利润同比

		String totalStartTime  = "";
		String totalEndTime = "";
		int statDateType = 0;
		boolean isRelative = false;//是否环比
		boolean isSameRatio = false;//是否同比
		String relativeStartTime = "";
		String relativeEndTime = "";
		BigDecimal oneHundred = new BigDecimal("100");
		String sameTime = "";
		if(dateType == 0){//昨日
			totalStartTime = yesterday;
			totalEndTime = yesterday;
		}else if(dateType == 1){//本月
			totalStartTime = thisMonth;
			totalEndTime = thisMonth;
			statDateType = 1;
			isRelative = true;
			relativeStartTime = beforeMonth;
			relativeEndTime = beforeMonth;
			isSameRatio = true;
			sameTime = lastYearMonth;
		}else {//本年
			totalStartTime = thisYear+"-01";
			totalEndTime = thisYear+"-12";
			statDateType = 1;
			isRelative = true;
			relativeStartTime = beforeYear+"-01";
			relativeEndTime = beforeYear+"-12";
		}

		//获取汇总
		List<Map<String, Object>> totalList = biMapper.getBiFlowAnalysisCountByTotal(totalStartTime,totalEndTime,statDateType);
		if(totalList!=null && totalList.size()>0){
			List<Map<String, Object>> totalListIncome = totalList.stream()
					.filter(item->Integer.parseInt(item.get("dataType").toString()) == BiFlowAnalysisEnum.DataType.INCOME.value)
					.collect(Collectors.toList());
			List<Map<String, Object>> totalListOutcome = totalList.stream()
					.filter(item->Integer.parseInt(item.get("dataType").toString()) == BiFlowAnalysisEnum.DataType.OUTCOME.value)
					.collect(Collectors.toList());
			List<Map<String, Object>> totalListProfit = totalList.stream()
					.filter(item->Integer.parseInt(item.get("dataType").toString()) == BiFlowAnalysisEnum.DataType.PROFIT.value)
					.collect(Collectors.toList());
			if(totalListIncome.size()>0){
				totalIncome = new BigDecimal(totalListIncome.get(0).get("amount").toString());
			}
			if(totalListOutcome.size()>0){
				totalOutcome = new BigDecimal(totalListOutcome.get(0).get("amount").toString());
			}
			if(totalListProfit.size()>0){
				totalProfit = new BigDecimal(totalListProfit.get(0).get("amount").toString());
			}
		}


		//获取环比
		if(isRelative){
			List<Map<String, Object>> relativeList = biMapper.getBiFlowAnalysisCountByTotal(relativeStartTime,relativeEndTime,statDateType);
			if(relativeList!=null && relativeList.size()>0){
				List<Map<String, Object>> relativeListIncome = relativeList.stream()
						.filter(item->Integer.parseInt(item.get("dataType").toString()) == BiFlowAnalysisEnum.DataType.INCOME.value)
						.collect(Collectors.toList());
				List<Map<String, Object>> relativeListOutcome = relativeList.stream()
						.filter(item->Integer.parseInt(item.get("dataType").toString()) == BiFlowAnalysisEnum.DataType.OUTCOME.value)
						.collect(Collectors.toList());
				List<Map<String, Object>> relativeListProfit = relativeList.stream()
						.filter(item->Integer.parseInt(item.get("dataType").toString()) == BiFlowAnalysisEnum.DataType.PROFIT.value)
						.collect(Collectors.toList());

				if(relativeListIncome.size()>0){
					BigDecimal beforeIncome =  new BigDecimal(relativeListIncome.get(0).get("amount").toString());
					if(beforeIncome.compareTo(BigDecimal.ZERO)!=0){
						relativeIncome = (totalIncome.subtract(beforeIncome)).divide(beforeIncome, 4, RoundingMode.HALF_UP).multiply(oneHundred);
					}
				}
				if(relativeListOutcome.size()>0){
					BigDecimal beforeOutcome =  new BigDecimal(relativeListOutcome.get(0).get("amount").toString());
					if(beforeOutcome.compareTo(BigDecimal.ZERO)!=0){
						relativeOutcome = (totalOutcome.subtract(beforeOutcome)).divide(beforeOutcome, 4, RoundingMode.HALF_UP).multiply(oneHundred);
					}
				}
				if(relativeListProfit.size()>0){
					BigDecimal beforeProfit =  new BigDecimal(relativeListProfit.get(0).get("amount").toString());
					if(beforeProfit.compareTo(BigDecimal.ZERO)!=0){
						relativeProfit = (totalProfit.subtract(beforeProfit)).divide(beforeProfit, 4, RoundingMode.HALF_UP).multiply(oneHundred);
					}
				}

			}
		}
		//获取同比
		if(isSameRatio){
			List<Map<String, Object>> sameList = biMapper.getBiFlowAnalysisCountByTotal(sameTime,sameTime,statDateType);
			if(sameList!=null && sameList.size()>0){
				List<Map<String, Object>> sameListIncome = sameList.stream()
						.filter(item->Integer.parseInt(item.get("dataType").toString()) == BiFlowAnalysisEnum.DataType.INCOME.value)
						.collect(Collectors.toList());
				List<Map<String, Object>> sameListOutcome = sameList.stream()
						.filter(item->Integer.parseInt(item.get("dataType").toString()) == BiFlowAnalysisEnum.DataType.OUTCOME.value)
						.collect(Collectors.toList());
				List<Map<String, Object>> sameListProfit = sameList.stream()
						.filter(item->Integer.parseInt(item.get("dataType").toString()) == BiFlowAnalysisEnum.DataType.PROFIT.value)
						.collect(Collectors.toList());
				if(sameListIncome.size()>0){
					BigDecimal beforeIncome =  new BigDecimal(sameListIncome.get(0).get("amount").toString());
					if(beforeIncome.compareTo(BigDecimal.ZERO)!=0){
						sameRatioIncome = (totalIncome.subtract(beforeIncome)).divide(beforeIncome, 4, RoundingMode.HALF_UP).multiply(oneHundred);
					}
				}
				if(sameListOutcome.size()>0){
					BigDecimal beforeOutcome =  new BigDecimal(sameListOutcome.get(0).get("amount").toString());
					if(beforeOutcome.compareTo(BigDecimal.ZERO)!=0){
						sameRatioOutcome = (totalOutcome.subtract(beforeOutcome)).divide(beforeOutcome, 4, RoundingMode.HALF_UP).multiply(oneHundred);
					}
				}
				if(sameListProfit.size()>0){
					BigDecimal beforeProfit =  new BigDecimal(sameListProfit.get(0).get("amount").toString());
					if(beforeProfit.compareTo(BigDecimal.ZERO)!=0){
						sameRatioProfit = (totalProfit.subtract(beforeProfit)).divide(beforeProfit, 4, RoundingMode.HALF_UP).multiply(oneHundred);
					}
				}

			}
		}
		res.put("totalIncome",totalIncome);//昨日收入
		res.put("totalOutcome",totalOutcome);//昨日支出
		res.put("totalProfit",totalProfit);//昨日利润
		res.put("relativeIncome",relativeIncome.setScale(2, RoundingMode.HALF_UP));//收入环比
		res.put("relativeOutcome",relativeOutcome.setScale(2, RoundingMode.HALF_UP));//支出环比
		res.put("relativeProfit",relativeProfit.setScale(2, RoundingMode.HALF_UP));//利润环比
		res.put("sameRatioIncome",sameRatioIncome.setScale(2, RoundingMode.HALF_UP));//收入同比
		res.put("sameRatioOutcome",sameRatioOutcome.setScale(2, RoundingMode.HALF_UP));//支出同比
		res.put("sameRatioProfit",sameRatioProfit.setScale(2, RoundingMode.HALF_UP));//利润同比


		//获取所有财务交易类型信息
		//List<TcwFinancialTransactionType> typeList = new TcwFinancialTransactionType().setStatus(1).queryList();
		//获取扇形图表信息
		if(dateType == 0){//昨日
			List<Map<String, Object>> echarList = new BiFlowAnalysis().setStatDate(yesterday)
					.addLeftJoin("TCW_FinancialTransactionType F ON F.Bid = A.FinancialTransactionTypeBid")
					.addField("F.IntegrityType AS integrityType")//完整类型
					.queryMap();
			res.put("echarList",echarList);
		}else if(dateType == 1){//本月
			List<Map<String, Object>> echarList = new BiFlowAnalysis().setStatDate(thisMonth)
					.addLeftJoin("TCW_FinancialTransactionType F ON F.Bid = A.FinancialTransactionTypeBid")
					.addField("F.IntegrityType AS integrityType")//完整类型
					.queryMap();
			res.put("echarList",echarList);
		}else {//本年
			List<Map<String, Object>> echarList = biMapper.getBiFlowAnalysisCountGroupByFinancialTransactionType(totalStartTime,totalEndTime);
			res.put("echarList",echarList);
		}

		return res;
	}







}
